home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / misc / unix / tracker_4_3.lzh / tracker / Unix / ui.c
Encoding:
C/C++ Source or Header  |  1994-02-13  |  8.0 KB  |  443 lines

  1. /* unix/ui.c 
  2.     vi:se ts=3 sw=3:
  3.  */
  4.  
  5. /* special termio discipline for sun/sgi,
  6.  * for non blocking io and such.
  7.  * These functions should not be too difficult
  8.  * to write for a PC.
  9.  */
  10. /* $Id: ui.c,v 4.1 1994/01/13 09:18:48 espie Exp espie $
  11.  * $Log: ui.c,v $
  12.  * Revision 4.1  1994/01/13  09:18:48  espie
  13.  * *** empty log message ***
  14.  *
  15.  * Revision 4.0  1994/01/11  18:02:31  espie
  16.  * Major change: lots of new calls.
  17.  *
  18.  * Revision 1.1  1994/01/08  04:00:36  Espie
  19.  * Initial revision
  20.  *
  21.  * Revision 1.2  1993/12/26  18:54:21  Espie
  22.  * Modified in a more consistent way.
  23.  *
  24.  * Revision 1.1  1993/12/26  00:55:53  Espie
  25.  * Initial revision
  26.  *
  27.  * Revision 3.15  1993/12/04  16:12:50  espie
  28.  * BOOL -> boolean.
  29.  *
  30.  * Revision 3.14  1993/11/17  15:31:16  espie
  31.  * *** empty log message ***
  32.  *
  33.  * Revision 3.13  1993/10/06  17:17:45  espie
  34.  * Stupid termio bug: shouldn't restore term to sanity if we don't
  35.  * know what sanity is. For instance, if we haven't modified anything.
  36.  *
  37.  * Revision 3.11  1993/07/17  12:00:30  espie
  38.  * Added other commands (numerous).
  39.  *
  40.  * Revision 3.10  1993/07/14  16:33:41  espie
  41.  * Added partial code for hpux.
  42.  *
  43.  * Revision 3.9  1993/04/28  20:14:41  espie
  44.  * My error...
  45.  *
  46.  * Revision 3.8  1993/04/25  14:50:17  espie
  47.  * cflags interpreted correctly.
  48.  *
  49.  * Revision 3.7  1993/01/16  16:23:33  espie
  50.  * Hsavolai fix.
  51.  *
  52.  * Revision 3.6  1993/01/15  14:00:28  espie
  53.  * Added bg/fg test.
  54.  *
  55.  * Revision 3.5  1993/01/06  17:58:39  espie
  56.  * Added changes for linux.
  57.  *
  58.  * Revision 3.4  1992/12/03  15:00:50  espie
  59.  * restore stty.
  60.  *
  61.  * Revision 3.3  1992/11/27  10:29:00  espie
  62.  * General cleanup
  63.  *
  64.  * Revision 3.2  1992/11/22  17:20:01  espie
  65.  * Added update_frequency call, mostly unchecked
  66.  *
  67.  * Revision 3.1  1992/11/19  20:44:47  espie
  68.  * Protracker commands.
  69.  *
  70.  */
  71.  
  72. #ifdef dec
  73. #define stub_only
  74. #endif
  75.  
  76. #if defined(linux) || defined(__386BSD__)
  77. #include <termios.h>
  78. #else
  79. #ifdef __hpux
  80. #include <sys/bsdtty.h>
  81. #endif
  82. #include <sys/termio.h>
  83. #endif
  84. #ifdef __386BSD__
  85. #include <sys/ioctl.h>
  86. #endif
  87. #include <stdio.h>
  88. #include <signal.h>
  89. #include "defs.h"
  90. #include "extern.h"
  91. #include "tags.h"
  92. #include "prefs.h"
  93.  
  94.  
  95. LOCAL void nonblocking_io P((void));
  96. LOCAL void sane_tty P((void));
  97.  
  98. LOCAL void (*INIT)P((void)) = nonblocking_io;
  99.  
  100.  
  101. LOCAL boolean show;
  102. /* poor man's timer */
  103. LOCAL int current_pattern;
  104. LOCAL int count_pattern, count_song;
  105. #define SMALL_DELAY 25
  106.  
  107. /* do not define any stdio routines if it's known not to work */
  108.  
  109. #ifdef stub_only
  110.  
  111. boolean run_in_fg()
  112.    {
  113.    return TRUE;
  114.    }
  115.  
  116. LOCAL void sane_tty()
  117.    {
  118.    }
  119.  
  120. LOCAL struct tag end_marker;
  121.  
  122. struct tag *get_ui()
  123.    {
  124.    end_marker.type = TAG_END;
  125.    return &end_marker;
  126.    }
  127.  
  128. #else
  129.  
  130. LOCAL struct termio sanity;
  131. LOCAL struct termio *psanity = 0;
  132.  
  133. LOCAL boolean is_fg;
  134.  
  135. /* signal handler */
  136.  
  137. LOCAL void goodbye(sig)
  138. int sig;
  139.     {
  140.     static char buffer[25];
  141.  
  142.     sprintf(buffer, "Signal %d", sig);
  143.     end_all(buffer);
  144.     }
  145.  
  146. LOCAL void abort_this(sig)
  147. int sig;
  148.    {
  149.    end_all("Abort");
  150.    }
  151.  
  152. #ifdef SIGTSTP
  153. LOCAL void suspend(sig)
  154. int sig;
  155.    {
  156.    fflush(stdout);
  157.    sane_tty();
  158.    signal(SIGTSTP, SIG_DFL);
  159.    kill(0, SIGTSTP);
  160.    }
  161. #endif
  162.  
  163. boolean run_in_fg()
  164.    {
  165.    int val;
  166.  
  167. #ifdef __hpux
  168.     if (!isatty(fileno(stdin)) || !isatty(fileno(stdout)))
  169.         return FALSE;
  170. #endif
  171.  
  172.    /* real check for running in foreground */
  173.    if (ioctl(fileno(stdin), TIOCGPGRP, &val))
  174.       return FALSE; 
  175.    if (val == getpgrp())
  176.       return TRUE;
  177.    else
  178.       return FALSE;
  179.    }
  180.  
  181. LOCAL void switch_mode()
  182.    {
  183.    struct termio zap;
  184.  
  185. #ifdef SIGTSTP
  186.    signal(SIGTSTP, suspend);
  187. #endif
  188.    signal(SIGCONT, switch_mode);
  189.    signal(SIGINT, goodbye);
  190.    signal(SIGQUIT, goodbye);
  191.    signal(SIGUSR1, abort_this);
  192.  
  193.    if (run_in_fg())
  194.       {
  195. #ifdef __386BSD__
  196.       tcgetattr(fileno(stdin), &zap);
  197. #else
  198.       ioctl(fileno(stdin), TCGETA, &zap);
  199. #endif
  200. #ifdef linux
  201.       zap.c_cc[VMIN] = 0;
  202.       zap.c_cc[VTIME] = 0;
  203. /* Commented out
  204. As Hannu said:
  205. The current Linux kernel interprets correctly the c_lflags field so it
  206. should be set like for the other systems. 
  207.       zap.c_lflag = 0;
  208.  */
  209. #else
  210. #ifdef __386BSD__
  211.       zap.c_cc[VMIN] = 0;     /* can't work with old */
  212.       zap.c_cc[VTIME] = 0; /* FreeBSD versions    */
  213.       zap.c_lflag &= ~(ICANON|ECHO|ECHONL);
  214. #endif
  215.       zap.c_cc[VEOL] = 0;
  216.       zap.c_cc[VEOF] = 0;
  217. #endif
  218.       zap.c_lflag &= ~(ICANON | ECHO);
  219. #ifdef __386BSD__
  220.       tcsetattr(fileno(stdin, TCSANOW, &zap);
  221. #else
  222.       ioctl(fileno(stdin), TCSETA, &zap);
  223. #endif
  224.       is_fg = TRUE;
  225.       }
  226.    else
  227.       is_fg = FALSE;
  228.    }
  229.  
  230. /* nonblocking_io():
  231.  * try to setup the keyboard to non blocking io
  232.  */
  233. LOCAL void nonblocking_io()
  234.    {
  235.    show = get_pref_scalar(PREF_SHOW);
  236.    /* try to renice our own process to get more cpu time */
  237.    if (nice(-15) == -1)
  238.       nice(0);
  239.    if (!psanity)
  240.       {
  241.       psanity = &sanity;
  242. #ifdef __386BSD__
  243.       tcgetattr(fileno(stdin), &sanity);
  244. #else
  245.       ioctl(fileno(stdin), TCGETA, psanity);
  246. #endif
  247.       }
  248.    switch_mode();
  249.    at_end(sane_tty);
  250.    }
  251.  
  252.  
  253. /* sane_tty():
  254.  * restores everything to a sane state before returning to shell */
  255. LOCAL void sane_tty()
  256.    {
  257. #ifdef __386BSD__
  258.       tcsetattr(fileno(stdin), &sanity);
  259. #else
  260.       ioctl(fileno(stdin), TCSETA, psanity);
  261. #endif
  262.    }
  263.  
  264. LOCAL int may_getchar()
  265.    {
  266.    char buffer;
  267.  
  268.    INIT_ONCE;
  269.  
  270.    if (run_in_fg() && !is_fg)
  271.       switch_mode();
  272.    if (run_in_fg() && read(fileno(stdin), &buffer, 1))
  273.       return buffer;
  274.    return EOF;
  275.    }
  276.  
  277. LOCAL struct tag result[2];
  278.  
  279. struct tag *get_ui()
  280.    {
  281.    result[0].type = TAG_END;
  282.    result[1].type = TAG_END;
  283.    count_pattern++;
  284.    count_song++;
  285.    switch(may_getchar())
  286.       {
  287.    case 'n':
  288.       result[0].type = UI_NEXT_SONG;
  289.       break;
  290.    case 'p':
  291.       if (count_song > SMALL_DELAY)
  292.          result[0].type = UI_RESTART;
  293.       else
  294.          result[0].type = UI_PREVIOUS_SONG;
  295.       count_song = 0;
  296.       break;
  297.    case 'x':
  298.    case 'e':
  299.    case 'q':
  300.       result[0].type = UI_QUIT;
  301.       break;
  302.    case 's':
  303.       result[0].type = UI_SET_BPM;
  304.       result[0].data.scalar = 50;
  305.       break;
  306.    case 'S':
  307.       result[0].type = UI_SET_BPM;
  308.       result[0].data.scalar = 60;
  309.       break;
  310.    case '>':
  311.       result[0].type = UI_JUMP_TO_PATTERN;
  312.       result[0].data.scalar = current_pattern + 1;
  313.       break;
  314.    case '<':
  315.       result[0].type = UI_JUMP_TO_PATTERN;
  316.       result[0].data.scalar = current_pattern;
  317.       if (count_pattern < SMALL_DELAY)
  318.          result[0].data.scalar--;
  319.       break;
  320.    case '?':
  321.       show = !show;
  322.         set_pref_scalar(PREF_SHOW, show);
  323.         if (show)
  324.             putchar('\n');
  325.       break;
  326.    default:
  327.       break;
  328.       }
  329.    return result;
  330.    }
  331.       
  332.          
  333. #endif
  334.  
  335.  
  336. void notice(s)
  337. char *s;
  338.    {
  339.    fprintf(stderr, "%s\n", s);
  340.    }
  341.  
  342. void status(s)
  343. char *s;
  344.    {
  345.    if (run_in_fg())
  346.       {
  347.         if (s)
  348.          {
  349.          puts(s);
  350.          }
  351.       else
  352.          putchar('\n');
  353.       }
  354.    }
  355.  
  356. LOCAL char title[25];
  357. void song_title(s)
  358. char *s;
  359.    {
  360.     strncpy(title, s, 25);
  361.     if (run_in_fg() && !show)
  362.         puts(title);
  363.    count_song = 0;
  364.    }
  365.  
  366.  
  367. LOCAL char scroll_buffer[80];
  368.  
  369. GENERIC begin_info(title)
  370. char *title;
  371.    {
  372.    if (run_in_fg())
  373.       return scroll_buffer;
  374.    else
  375.       return 0;
  376.    }
  377.  
  378. void infos(handle, s)
  379. GENERIC handle;
  380. char *s;
  381.    {
  382.    if (handle)
  383.       printf(s);
  384.    }
  385.  
  386. void info(handle, line)
  387. GENERIC handle;
  388. char *line;
  389.    {
  390.    if (handle)
  391.       puts(line);
  392.    }
  393.  
  394. void end_info(handle)
  395. GENERIC handle;
  396.    {
  397.    if (handle)
  398.       fflush(stdout);
  399.    }
  400.  
  401. LOCAL char *last_result = 0;
  402.  
  403. char *new_scroll(void)
  404.    {
  405.    if (run_in_fg())
  406.       {
  407.       last_result = scroll_buffer;
  408.       strcpy(scroll_buffer, "             |             |             |             ");
  409.       }
  410.    else
  411.       last_result = 0;
  412.    return last_result;
  413.    }
  414.    
  415. void scroll()
  416.    {
  417.    if (run_in_fg() && last_result)
  418.         {
  419.       puts(scroll_buffer);
  420.         fflush(stdout);
  421.         }
  422.    }
  423.  
  424. void display_pattern(current, total)
  425. int current, total;
  426.    {
  427.    if (run_in_fg())
  428.       {
  429.       if (show)
  430.          printf("\n%3d/%3d %s\n", current, total, title);
  431.       else
  432.          printf("%3d/%3d\b\b\b\b\b\b\b", current, total);
  433.       fflush(stdout); 
  434.       }
  435.    current_pattern = current;
  436.    count_pattern = 0;
  437.    }
  438.  
  439. boolean checkbrk()
  440.    {
  441.    return FALSE;
  442.    }
  443.